#ifndef HTTPREQUEST_H
#define HTTPREQUEST_H

#include <string>
#include <regex>
#include <unordered_map>
#include <unordered_set>
#include <errno.h>
#include <mysql/mysql.h>

#include "../buffer/buffer.h"
#include "../log/log.h"
#include "../pool/sqlconnpool.h"
#include "../pool/sqlconnRAII.h"

class HttpRequest {
public:
    // 解析状态
    enum class PARSE_STATE {
        REQUEST_LINE,   // 解析请求行
        HEADERS,        // 解析请求头
        BODY,           // 解析请求体
        FINISH,         // 解析完成
    };

    // 响应状态
    enum class HTTP_CODE {
        NO_REQUEST = 0,     // 请求未完成
        GET_REQUEST,        // 成功解析get请求
        BAD_REQUEST,        // 请求格式错误
        NO_RESOURSE,        // 请求资源不存在
        FORBIDDENT_REQUEST, // 请求被禁止 
        FILE_REQUEST,       // 请求的是文件
        INTERNAL_ERROR,     // 服务器内部错误
        CLOSED_CONNECTION,  // 连接已关闭
    };
public:
    HttpRequest();
    ~HttpRequest() = default;

    void init();
    bool parse(Buffer& buff);

    std::string  path() const;
    std::string& path();
    std::string method() const;
    std::string version() const;

    std::string getPost(const char* key) const;
    std::string getPost(const std::string& key) const;

    bool isKeepAlive() const;
private:
    bool parseRequestLine(const std::string& line);
    void parseRequestHeader(const std::string& line);
    void parseRequestBody(const std::string& line);

    void parseRequestPath();
    void parseRequestPost();
    void parseFromUrlencoded();

    // 验证用户登录信息
    static bool userVerify(const std::string& name, 
                            const std::string& pwd, bool isLogin);
    // 将一个十六进制字符转换为对应的整数值
    static int converHex(char ch);
private:
    PARSE_STATE parseState_;

    std::string method_;
    std::string path_;
    std::string version_;
    std::string body_;

    std::unordered_map<std::string, std::string> header_;
    std::unordered_map<std::string, std::string> post_;

    static const std::unordered_set<std::string> defaultHtml_;
    static const std::unordered_map<std::string, int> defaultHtmlTag_;
};

#endif